package com.bifang.core.qrcode.util;

import cn.hutool.core.img.BackgroundRemoval;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import com.bifang.common.constant.enums.common.QrcodeColorEnum;
import com.bifang.common.exception.AppException;
import com.bifang.common.vo.AppCodeVO;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import java.awt.Color;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** 码工具类 * */
public class CodeUtil {
    private static final String _str =
            "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    private static char[] charSet = _str.toCharArray();
    private static int checkNum = 10;
    private static final Logger logger = LoggerFactory.getLogger(CodeUtil.class);
    /** 生成码编号 */
    public static String createCode(AppCodeVO appCodeVO) {
        if (StringUtils.isBlank(appCodeVO.getCodePro())) {
            throw new AppException("码属性不能为空");
        }
        if (StringUtils.isBlank(appCodeVO.getCodeType())) {
            throw new AppException("码类型不能为空");
        }
        String code =
                appCodeVO.getCodePro()
                        + appCodeVO.getCodeType()
                        + appCodeVO.getAppType()
                        + appCodeVO.getApplyType();
        code = code + appCodeVO.getApplyTime();
        code = code + RandomUtil.randomNumbers(3) + letterToNumber(appCodeVO.getUniqueId());
        return code + CodeUtil.getCheckCode(code);
    }
    /** 字符串和 */
    public static int letterToNumber(String letter) {
        int length = letter.length();
        int number = 0;
        char[] chList = letter.toCharArray();
        for (int i = 0; i < length; i++) {
            char ch = chList[i];
            int num = ch;
            number += num;
        }
        return number;
    }
    /** 动态码 */
    public static BufferedImage getCodeImg(AppCodeVO appCodeVO) {
        QrConfig config = new QrConfig(300, 300);
        config.setErrorCorrection(ErrorCorrectionLevel.H);
        // 设置边距，既二维码和背景之间的边距
        config.setMargin(1);
        // 设置前景色，既二维码颜色 默认为黑色
        QrcodeColorEnum qrcodeColorEnum = QrcodeColorEnum.getByType(appCodeVO.getCodeColor());
        Color codeColor = Color.BLACK;
        if (qrcodeColorEnum == null) {
            try {
                if (appCodeVO.getCodeColor() != null) {
                    codeColor = BackgroundRemoval.hexToRgb(appCodeVO.getCodeColor());
                }
            } catch (Exception e) {
                logger.error("码颜色传入数据格式不正确", e);
            }
        } else {
            codeColor = qrcodeColorEnum.getColor();
        }
        config.setForeColor(codeColor);

        if (StringUtils.isNotBlank(appCodeVO.getImgPath())) {
            try {
                URL url = new URL(appCodeVO.getImgPath());
                Image image = ImgUtil.read(url).getScaledInstance(80, 80, Image.SCALE_DEFAULT);
                config.setImg(image);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
        }
        QrcodeColorEnum backColorEnum = QrcodeColorEnum.getByType(appCodeVO.getBackColor());
        Color backColor = Color.WHITE;
        if (backColorEnum == null) {
            // 设置背景色（白色）
            try {
                if (appCodeVO.getBackColor() != null) {
                    backColor = BackgroundRemoval.hexToRgb(appCodeVO.getBackColor());
                }
            } catch (Exception e) {
                logger.error("码背景颜色传入数据格式不正确", e);
            }
        } else {
            backColor = backColorEnum.getColor();
        }
        config.setBackColor(backColor);
        return QrCodeUtil.generate(appCodeVO.getCode(), config);
    }
    /**
     * 添加校验位
     *
     * @param str
     * @return
     */
    private static char getCheckCode(String str) {
        BigDecimal unm = new BigDecimal(str).add(BigDecimal.valueOf(checkNum));
        int a = Integer.valueOf(unm.divideAndRemainder(BigDecimal.valueOf(62))[1].toString());
        return charSet[a];
    }
    /**
     * 校验短链是否正确
     *
     * @param link
     * @return
     */
    public static boolean checkShortLink(String link) {
        if (link == null) {
            return false;
        }
        if (link.length() <= 18) {
            return false;
        }
        String substring = link.substring(0, link.length() - 1);
        char charAt = link.charAt(link.length() - 1);
        char checkCode = getCheckCode(substring);
        if ((int) charAt == (int) (checkCode)) {
            return true;
        }
        return false;
    }
}
